
#include "user.h"
#include <stdlib.h>

uint32_t led_blink_callback_time_ms = 0;
uint32_t serial_update_callback_time_ms = 0;
uint32_t led_blink_time = 1000;
uint32_t camera_loop_update = 0;
uint32_t camera_trigger_count = 0;

uint32_t camera_auto_trigger_cycle = 800;   //相机自动触发周期ms
uint32_t camera_auto_trigger_time = 10;
uint32_t camera_old_trigger_time = 0;

uint8_t camera_process_ok = 0;
uint8_t wait_exit = 0;

Camera camera[5];

extern TIM_HandleTypeDef htim1;

static uint8_t camera_action_is_stop(void)
{
	uint8_t i = 0;
	for( i=0; i<5; ++i )
	{
		if( 1==camera[i].camera_trigger_enable )
		{
			return 0;
		}			
	}
	return 1;
}

void init_system(void)
{
	HAL_TIM_Base_Start_IT(&htim1);
	serial_init();
	camera_init();
}

void app(void)
{	
	uint32_t len = 0;
	uint8_t buff[6] = {'\0'};
	int i = 0;
	char buf[64];
	
	time_5ms_callback();
	serial_process_callback();
	
	//判断开始
	if( camera_process_ok==0 )
	{
		int32_t auto_loop_time = 0;
		int32_t camera_tg_time = 0;
		int32_t random_en = 0;
		
		//获取自动触发周期和触发时间
		char res[64] = {'\0'};
		len = serial_read(SERIAL_ID_USB, buff, 63);
		if(len>0)
			sscanf((const char*)buff, "%s %d %d %d\r\n", res, &auto_loop_time, &camera_tg_time, &random_en); 
		
		if( strcmp("start", res)==0 )
		{
			if( auto_loop_time>0 ) 
				camera_auto_trigger_cycle = auto_loop_time;
			else camera_auto_trigger_cycle = 800;
			
			if( camera_tg_time>0 && camera_tg_time<=500 ) 
				camera_auto_trigger_time = camera_tg_time;
			else camera_auto_trigger_time = 10;
			
			if( auto_loop_time<=camera_tg_time ) camera_auto_trigger_cycle += camera_tg_time+50;
			
			for( i=0; i<5; i++ )
			{
				camera[i].camera_loop_time = camera_auto_trigger_cycle;
				camera[i].camera_trigeer_time = camera_auto_trigger_time;
				camera[i].camera_trigger_enable = 1; 
				camera[i].random_wait_enable = (random_en=1);
			}
			
			camera_process_ok = 1;
			led_blink_time = 100;
			serial_write(SERIAL_ID_USB, (uint8_t*)"Camera Trigger Starting!\r\n", strlen("Camera Trigger Starting!\r\n"));
			sprintf(buf, "Cycle, Trigger, Random = %d %d %d\r\n", camera_auto_trigger_cycle, camera_auto_trigger_time, random_en);
			serial_write(SERIAL_ID_USB, (uint8_t*)buf, strlen(buf));
			
			HAL_Delay(5);			
			camera_old_trigger_time = get_system_time_ms();
		}
	}
	
	//判断结束
	else if( camera_process_ok==1 )
	{
		char res[64] = {'\0'};
		serial_read(SERIAL_ID_USB, (uint8_t*)res, 4);
		res[4] = '\0';
		
		if( strcmp("exit", res)==0 )
		{	
			wait_exit = 1;
		}
	}
	
	if( wait_exit && camera_action_is_stop())
	{
		wait_exit = 0;
		camera_process_ok = 0;	
		led_blink_time = 1000;
		for( i=0; i<5; ++i )
		{
			camera[i].camera_level=1;
			camera[i].camera_trigger_enable = 0;
			camera_trigger(&camera[i], GPIO_PIN_SET);
		}
		
		sprintf(buf, "Camera Trigger END,Count=%d!\r\n", camera_trigger_count);
		serial_write(SERIAL_ID_USB, (uint8_t*)buf, strlen(buf));
	}
	
	//自动执行拍照
	if( camera_process_ok )
	{ 
		camera_update();
	}
	
}

void time_5ms_callback(void)
{
	if( get_system_time_ms()-led_blink_callback_time_ms>=5 )
	{
		led_callback(led_blink_time);
		led_blink_callback_time_ms = get_system_time_ms();
	}
}

/// 每隔5ms调用一次led
void led_callback(uint32_t blink_time)
{
	static uint32_t count = 0;
	
	++count;
	
	if( count*5<=led_blink_time )
	{
		led(OFF);
	}else if( count*5<=2*led_blink_time )
	{
		led(ON);
	}else
	{
		count = 0;
	}
}

/// 相机初始化
void camera_init(void)
{
	uint8_t i = 0;
	camera[0].pin = CAMERA_FRONT_PIN;
	camera[1].pin = CAMERA_BEHIND_PIN;
	camera[2].pin = CAMERA_LEFT_PIN;
	camera[3].pin = CAMERA_RIGHT_PIN;
	camera[4].pin = CAMERA_CENTER_PIN;
	
	for( i=0; i<5; ++i )
	{
	  camera_trigger(&camera[i], GPIO_PIN_SET);
		camera[i].camera_trigger_enable = 0;  //无法进行拍照
		camera[i].camera_trigger_cmpt = 1;
		camera[i].camera_level = 1;           //当前电平
		camera[i].camera_trigeer_old_time = 0;
		camera[i].camera_loop_time = 1000;    //模拟拍照间隔
		camera[i].camera_trigeer_time = 10;   //相机固定触发10ms低电平
		camera[i].random_wait_time = 0;
		camera[i].random_wait_enable = 0;
	}
}

void camera_update(void)
{
	char buff[128];
	
	uint8_t i = 0;
	
	uint32_t current_time = get_system_time_ms();
	
	//随机设置新的轮询每一路相机触发等待时间
	if( current_time-camera_old_trigger_time>=camera_auto_trigger_cycle )
	{
		int r;
		for( i=0; i<5; i++ )
		{
			camera[i].random_wait_time = 0;
			if( camera[i].random_wait_enable )
			{
				srand(get_system_time_ms()+i*5);
				r = rand()%200;
				camera[i].random_wait_time = r;
				//sprintf(buff, "Camera[%d] %dms\r\n", i, r);
				//serial_write(SERIAL_ID_USB, (uint8_t*)buff, strlen(buff));
			}
			camera[i].camera_trigger_enable = 1;
		}
		camera_loop_update = 1;
		camera_old_trigger_time = current_time;
	}
	
	if( camera_loop_update )
	{
		//判断五路触发是否已经完成，完成则提前退出
		if( camera_action_is_stop() ) 
		{
			camera_loop_update = 0;
			++camera_trigger_count;
			sprintf(buff, ">> Camera trigeer Count = %d\r\n", camera_trigger_count);
			serial_write(SERIAL_ID_USB, (uint8_t*)buff, strlen(buff));
			return;
		}		
		
		//执行电平翻转动作
		for( i=0; i<5; ++i )
		{
			if( camera[i].camera_trigger_enable )
			{
				if( get_system_time_ms()-camera_old_trigger_time>camera[i].random_wait_time && camera[i].camera_level==1)
				{
					//拉低
					camera[i].camera_trigeer_old_time = get_system_time_ms();
					camera[i].camera_level = 0;
					camera_trigger(&camera[i], GPIO_PIN_RESET);
				}
				
				if( camera[i].camera_level==0 && get_system_time_ms()-camera[i].camera_trigeer_old_time>=camera[i].camera_trigeer_time )
				{
					//拉高
					camera[i].camera_level = 1;
					camera[i].camera_trigger_enable = 0;
					camera_trigger(&camera[i], GPIO_PIN_SET);
				}
			}
		}
	}
}

/// 相机触发调用
void camera_trigger(Camera* cam, GPIO_PinState sta)
{	
	switch( cam->pin )
	{
		case CAMERA_FRONT_PIN:
			HAL_GPIO_WritePin(GPIOA, cam->pin, sta);
			break;
		case CAMERA_BEHIND_PIN:
			HAL_GPIO_WritePin(GPIOA, cam->pin, sta);
			break;
		case CAMERA_LEFT_PIN:
			HAL_GPIO_WritePin(GPIOA, cam->pin, sta);
			break;
		case CAMERA_RIGHT_PIN:
			HAL_GPIO_WritePin(GPIOA, cam->pin, sta);
			break;
		case CAMERA_CENTER_PIN:
			HAL_GPIO_WritePin(GPIOA, cam->pin, sta);
			break;
		default:
			break;
	}
}

//准确系统参考时间
static __IO uint64_t system_time_us = 0; 

uint64_t get_system_time_us(void)
{
	__set_PRIMASK(1);
	
	uint64_t us = system_time_us + htim1.Instance->CNT;
	
	__set_PRIMASK(0);
	
	return us;
}

uint32_t get_system_time_ms(void)
{
	return (uint32_t)(get_system_time_us()/1000);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if( htim==&htim1 )
	{
		system_time_us += 65536;
	}
}

